<template>
  <div class="device-type-page">
    <div class="breadcrumb-container">
      <el-breadcrumb :separator-icon="ArrowRight" class="breadcrumb-nav">
        <el-breadcrumb-item :to="{ path: '/' }" class="breadcrumb-item">
          <el-icon class="breadcrumb-icon"><HomeFilled /></el-icon>
          <span>主页</span>
        </el-breadcrumb-item>
        <el-breadcrumb-item class="breadcrumb-item">
          <el-icon class="breadcrumb-icon"><Setting /></el-icon>
          <span>设备管理</span>
        </el-breadcrumb-item>
        <el-breadcrumb-item class="breadcrumb-item active">
          <el-icon class="breadcrumb-icon"><Menu /></el-icon>
          <span>设备类型</span>
        </el-breadcrumb-item>
      </el-breadcrumb>
    </div>
    <el-card class="filter-card" shadow="never">
      <el-form :model="searchForm" class="filter-form" inline @keyup.enter="handleSearch">
        <el-form-item>
          <el-input
            v-model="searchForm.device_typetree"
            placeholder="请输入设备类型编号/名称"
            clearable
          />
        </el-form-item>
        <el-form-item>
          <el-select
            v-model="searchForm.status"
            placeholder="请选择状态"
            clearable
            style="width: 180px"
          >
            <el-option
              v-for="item in statusOptions"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
        <div class="filter-actions">
          <el-button @click="handleReset">重置</el-button>
          <el-button type="primary" @click="handleSearch">查询</el-button>
        </div>
      </el-form>
    </el-card>

    <el-card class="table-card" shadow="never">
      <div class="toolbar">
        <el-button type="primary" @click="openCreateDialog">新增</el-button>
        <el-button :loading="importLoading" @click="triggerImport">导入</el-button>
        <el-button :loading="exportLoading" @click="handleExport">导出</el-button>
        <input
          ref="importInputRef"
          type="file"
          class="hidden-file-input"
          accept=".xlsx,.xls,.csv"
          @change="onImportChange"
        />
      </div>

      <el-table
        v-loading="loading"
        :data="data"
        border
        stripe
        class="device-type-table"
      >
        <el-table-column type="index" label="序号" width="70" align="center" />
        <el-table-column prop="device_typetree" label="设备类型名称" min-width="220">
          <template #default="scope">
            <div :class="['name-cell', `level-${scope.row.level ?? 1}`]">
              <!-- 展开/折叠箭头 -->
              <span v-if="scope.row.isParent" class="tree-arrow">▼</span>
              <span v-else class="tree-arrow tree-arrow-empty"></span>
              
              <!-- 层级缩进 -->
              <span :style="{ paddingLeft: `${(scope.row.level ? scope.row.level - 1 : 0) * 20}px` }" class="tree-indent"></span>
              
              <!-- 设备类型名称 -->
              <span class="tree-node-label">{{ scope.row.device_typetree }}</span>
            </div>
          </template>
        </el-table-column>
        <el-table-column prop="device_typecode" label="设备类型编号" min-width="180" />
        <el-table-column label="状态" width="120" align="center">
          <template #default="scope">
            <el-tag :type="scope.row.status == 1 || scope.row.status == 2">
              {{ getStatusLabel(scope.row.status) }}
            </el-tag>
           
          </template>
        </el-table-column>
        <el-table-column prop="bz" label="备注" min-width="220" show-overflow-tooltip />
        <el-table-column label="操作" width="160" align="center" fixed="right">
          <template #default="scope">
            <el-button type="primary" link @click="openEditDialog(scope.row)">编辑</el-button>
            <el-divider direction="vertical" />
            <el-button type="danger" link @click="handleDelete(scope.row)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-card>

    <el-dialog v-model="dialogVisible" :title="dialogTitle" width="520px" @closed="handleDialogClosed">
      <el-form
        ref="dialogFormRef"
        :model="dialogForm"
        :rules="dialogRules"
        label-width="110px"
      >
        <el-form-item label="上级类型" prop="parentId">
          <el-tree-select
            v-model="dialogForm.parentId"
            :data="parentTreeOptions"
            :props="treeSelectProps"
            placeholder="请选择上级类型"
            check-strictly
            clearable
            filterable
            style="width: 100%"
          />
        </el-form-item>
        <el-form-item label="设备类型名称" prop="deviceTypeName">
          <el-input v-model="dialogForm.deviceTypeName" placeholder="请输入设备类型名称" />
        </el-form-item>
        <el-form-item label="设备类型编号" prop="deviceTypeCode">
          <div class="code-field">
            <el-input
              v-model="dialogForm.deviceTypeCode"
              placeholder="请输入设备类型编号"
              :disabled="dialogForm.autoCode"
            />
            <el-switch
              v-model="dialogForm.autoCode"
              inline-prompt
              active-text="系统编号"
              inactive-text="系统编号"
              @change="handleAutoCodeToggle"
            />
          </div>
        </el-form-item>
        <el-form-item label="状态" prop="status">
          <el-radio-group v-model="dialogForm.status">
            <el-radio-button label="1">启用</el-radio-button>
            <el-radio-button label="0">禁用</el-radio-button>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="备注" prop="remark">
          <el-input
            v-model="dialogForm.remark"
            type="textarea"
            :rows="3"
            placeholder="请输入备注信息"
          />
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" :loading="submitLoading" @click="handleSubmit">
            确定
          </el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script lang="ts" setup>
import { computed, onMounted, reactive, ref, watch } from "vue";
import {
  ElMessage,
  ElMessageBox,
  type FormInstance,
  type FormRules,
} from "element-plus";
import https from "@/Http/http";
import { ArrowRight, HomeFilled, Setting, Menu } from "@element-plus/icons-vue";

interface DeviceTypeItem {
  id: number;
  deviceTypeName: string;
  deviceTypeCode: string;
  status: number | string;
  remark?: string;
  parentId?: number | null;
  level?: number;
}

const statusOptions = [
  { label: "启用", value: "1" },
  { label: "禁用", value: "2" },
];

const loading = ref(false);
const tableData = ref<DeviceTypeItem[]>([]);
const data = ref([])
const fetchList =  () => {
  https.Reads.get("/ADeviceManagement/ADevice_TypeShow", {
          params: {
            device_typetree: searchForm.device_typetree,
            status: searchForm.status,
          },
        }).then(res => {
            data.value = res.data.data
        });
    console.log(data.value)
};

const dialogVisible = ref(false);
const dialogMode = ref<"create" | "edit">("create");
const dialogTitle = computed(() =>
  dialogMode.value === "create" ? "新增设备类型" : "编辑设备类型"
);

const dialogFormRef = ref<FormInstance>();
const dialogForm = reactive({
  id: 0,
  deviceTypeName: "",
  deviceTypeCode: "",
  status: "1",
  remark: "",
  parentId: null as number | null,
  autoCode: true,
});

const dialogRules = reactive<FormRules>({
  parentId: [{ required: true, message: "请选择上级类型", trigger: "change" }],
  deviceTypeName: [
    { required: true, message: "请输入设备类型名称", trigger: "blur" },
  ],
  deviceTypeCode: [
    { required: true, message: "请输入设备类型编号", trigger: "blur" },
  ],
  status: [{ required: true, message: "请选择状态", trigger: "change" }],
});

const importInputRef = ref<HTMLInputElement | null>(null);
const submitLoading = ref(false);
const importLoading = ref(false);
const exportLoading = ref(false);

// 读写分别使用 https.Reads / https.Writes，路径使用相对 API 路径

const getStatusLabel = (value: number | string) =>
  statusOptions.find((item) => item.value === String(value))?.label ?? "未知";

const parentTreeOptions = ref<any[]>([]);
const treeSelectProps = {
  label: "label",
  children: "children",
  value: "value",
};
const ROOT_PARENT_VALUE = 0;

const generateDeviceCode = () => {
  const now = new Date();
  const pad = (num: number) => num.toString().padStart(2, "0");
  const timestamp = `${now.getFullYear()}${pad(now.getMonth() + 1)}${pad(
    now.getDate()
  )}${pad(now.getHours())}${pad(now.getMinutes())}${pad(now.getSeconds())}`;
  return `SBLXBH${timestamp}`;
};

const applyAutoCode = () => {
  if (dialogForm.autoCode) {
    dialogForm.deviceTypeCode = generateDeviceCode();
  }
};

watch(
  () => dialogForm.autoCode,
  () => {
    applyAutoCode();
  }
);
const searchForm = reactive({
  device_typetree: "",
  status: null,
});


const handleSearch = () => {
  fetchList();
};

const handleReset = () => {
  searchForm.device_typetree = "";
  searchForm.status = null;
  handleSearch();
};

const resetDialogForm = () => {
  dialogForm.id = 0;
  dialogForm.deviceTypeName = "";
  dialogForm.deviceTypeCode = "";
  dialogForm.status = "1";
  dialogForm.remark = "";
  dialogForm.parentId = null;
  dialogForm.autoCode = true;
  applyAutoCode();
  dialogFormRef.value?.clearValidate();
};

const openCreateDialog = () => {
  dialogMode.value = "create";
  resetDialogForm();
  dialogVisible.value = true;
};

const openEditDialog = (row: DeviceTypeItem) => {
  dialogMode.value = "edit";
  dialogForm.id = row.id;
  dialogForm.deviceTypeName = row.deviceTypeName;
  dialogForm.deviceTypeCode = row.deviceTypeCode;
  dialogForm.status = String(row.status ?? "1");
  dialogForm.remark = row.remark ?? "";
  dialogForm.parentId = row.parentId ?? ROOT_PARENT_VALUE;
  dialogForm.autoCode = false;
  dialogVisible.value = true;
};

const handleDialogClosed = () => {
  resetDialogForm();
};

const handleSubmit = () => {
  dialogFormRef.value?.validate(async (valid) => {
    if (!valid) return;
    submitLoading.value = true;
    try {
      const payload = {
        id: dialogForm.id,
        deviceTypeName: dialogForm.deviceTypeName,
        deviceTypeCode: dialogForm.deviceTypeCode,
        status: Number(dialogForm.status),
        remark: dialogForm.remark,
        parentId: dialogForm.parentId === ROOT_PARENT_VALUE ? null : dialogForm.parentId,
      };
      const request = dialogMode.value === "create"
        ? https.Writes.post(`/DeviceTypeAdd`, payload)
        : https.Writes.put(`/DeviceTypeUpdate`, payload);
      const { data } = await request;
      if (data?.code === 1) {
        ElMessage.success(data?.msg ?? "操作成功");
        dialogVisible.value = false;
        fetchList();
      } else {
        ElMessage.error(data?.msg ?? "操作失败");
      }
    } catch (error) {
      console.error("提交设备类型失败:", error);
      ElMessage.error("提交设备类型失败，请稍后重试");
    } finally {
      submitLoading.value = false;
    }
  });
};

const handleDelete = (row: DeviceTypeItem) => {
  ElMessageBox.confirm(`确认删除设备类型「${row.deviceTypeName}」吗？`, "提示", {
    confirmButtonText: "确认",
    cancelButtonText: "取消",
    type: "warning",
  })
    .then(async () => {
      try {
        const { data } = await https.Writes.put(`/DeviceTypeDelete`, {
          id: row.id,
        });
        if (data?.code === 1) {
          ElMessage.success(data?.msg ?? "删除成功");
          fetchList();
        } else {
          ElMessage.error(data?.msg ?? "删除失败");
        }
      } catch (error) {
        console.error("删除设备类型失败:", error);
        ElMessage.error("删除设备类型失败，请稍后重试");
      }
    })
    .catch(() => {});
};

const triggerImport = () => {
  if (!importLoading.value) {
    importInputRef.value?.click();
  }
};

const onImportChange = async (event: Event) => {
  const target = event.target as HTMLInputElement;
  const file = target.files?.[0];
  if (!file) {
    target.value = "";
    return;
  }
  const formData = new FormData();
  formData.append("file", file);
  importLoading.value = true;
  try {
    const { data } = await https.Writes.post(`/DeviceTypeImport`, formData, {
      headers: { "Content-Type": "multipart/form-data" },
    });
    if (data?.code === 1) {
      ElMessage.success(data?.msg ?? "导入成功");
      fetchList();
    } else {
      ElMessage.error(data?.msg ?? "导入失败");
    }
  } catch (error) {
    console.error("导入设备类型失败:", error);
    ElMessage.error("导入设备类型失败，请稍后重试");
  } finally {
    importLoading.value = false;
    target.value = "";
  }
};

const handleExport = async () => {
  if (exportLoading.value) return;
  exportLoading.value = true;
  try {
    const response = await https.Reads.get(`/DeviceTypeExport`, {
      params: {
        device_typetree: searchForm.device_typetree,
        status: searchForm.status,
      },
      responseType: "blob",
    });
    const blob = new Blob([response.data], {
      type:
        "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
    });
    const url = URL.createObjectURL(blob);
    const link = document.createElement("a");
    link.href = url;
    const timestamp = new Date()
      .toISOString()
      .replace(/[-:T]/g, "")
      .slice(0, 14);
    link.download = `设备类型_${timestamp}.xlsx`;
    link.click();
    URL.revokeObjectURL(url);
    ElMessage.success("导出任务已开始，请留意下载文件");
  } catch (error) {
    console.error("导出设备类型失败:", error);
    ElMessage.error("导出设备类型失败，请稍后重试");
  } finally {
    exportLoading.value = false;
  }
};



const buildTreeOptions = (items: DeviceTypeItem[]) => {
  const map = new Map<number, any>();
  const rootNode = {
    value: ROOT_PARENT_VALUE,
    label: "无上级类型",
    children: [] as any[],
  };
  const roots: any[] = [rootNode];
  items.forEach((item) => {
    map.set(item.id, {
      value: item.id,
      label: item.deviceTypeName,
      children: [],
    });
  });
  items.forEach((item) => {
    const node = map.get(item.id);
    if (item.parentId && map.has(item.parentId)) {
      map.get(item.parentId).children.push(node);
    } else {
      rootNode.children.push(node);
    }
  });
  return roots;
};

const handleAutoCodeToggle = () => {
  if (dialogForm.autoCode) {
    applyAutoCode();
  }
};

onMounted(() => {
  fetchList();
})
</script>

<style scoped>
.device-type-page {
  padding: 16px;
  min-height: 100%;
  box-sizing: border-box;
  position: relative;
  background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
  background-image: 
    url("data:image/svg+xml,%3Csvg width='100' height='100' viewBox='0 0 100 100' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11 18c3.866 0 7-3.134 7-7s-3.134-7-7-7-7 3.134-7 7 3.134 7 7 7zm48 25c3.866 0 7-3.134 7-7s-3.134-7-7-7-7 3.134-7 7 3.134 7 7 7zm-43-7c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zm63 31c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zM34 90c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zm56-76c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zM12 86c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm28-65c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm23-11c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm-6 60c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm29 22c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zM32 63c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm57-13c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm-9-21c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM60 91c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM35 41c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM12 60c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2z' fill='%23ffffff' fill-opacity='0.03' fill-rule='evenodd'/%3E%3C/svg%3E"),
    linear-gradient(135deg, #667eea15 0%, #764ba215 50%, #f093fb15 100%);
  background-size: 200px 200px, cover;
  background-position: 0 0, center;
  background-attachment: fixed;
}

.device-type-page::before {
  content: "";
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: 
    radial-gradient(circle at 20% 50%, rgba(102, 126, 234, 0.08) 0%, transparent 50%),
    radial-gradient(circle at 80% 80%, rgba(118, 75, 162, 0.08) 0%, transparent 50%),
    radial-gradient(circle at 40% 20%, rgba(240, 147, 251, 0.06) 0%, transparent 50%);
  pointer-events: none;
  z-index: 0;
}

.device-type-page > * {
  position: relative;
  z-index: 1;
}

.breadcrumb-container {
  margin-bottom: 20px;
  padding: 16px 20px;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  border-radius: 12px;
  box-shadow: 0 4px 12px rgba(102, 126, 234, 0.15);
  position: relative;
  z-index: 1;
  overflow: hidden;
}

.breadcrumb-container::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: url("data:image/svg+xml,%3Csvg width='60' height='60' viewBox='0 0 60 60' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cg fill='%23ffffff' fill-opacity='0.05'%3E%3Cpath d='M36 34v-4h-2v4h-4v2h4v4h2v-4h4v-2h-4zm0-30V0h-2v4h-4v2h4v4h2V6h4V4h-4zM6 34v-4H4v4H0v2h4v4h2v-4h4v-2H6zM6 4V0H4v4H0v2h4v4h2V6h4V4H6z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E");
  opacity: 0.3;
  pointer-events: none;
}

.breadcrumb-nav {
  position: relative;
  z-index: 1;
}

.breadcrumb-nav :deep(.el-breadcrumb__inner) {
  color: rgba(255, 255, 255, 0.9);
  font-weight: 500;
  font-size: 14px;
  transition: all 0.3s ease;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.breadcrumb-nav :deep(.el-breadcrumb__inner:hover) {
  color: #ffffff;
  transform: translateY(-1px);
}

.breadcrumb-nav :deep(.el-breadcrumb__separator) {
  color: rgba(255, 255, 255, 0.6);
  margin: 0 12px;
  font-size: 14px;
}

.breadcrumb-item {
  position: relative;
}

.breadcrumb-item.active :deep(.el-breadcrumb__inner) {
  color: #ffffff;
  font-weight: 600;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
}

.breadcrumb-item:not(.active) :deep(.el-breadcrumb__inner) {
  cursor: pointer;
}

.breadcrumb-item:not(.active) :deep(.el-breadcrumb__inner):hover {
  color: #ffffff;
  text-shadow: 0 0 8px rgba(255, 255, 255, 0.5);
}

.breadcrumb-icon {
  font-size: 16px;
  margin-right: 4px;
  vertical-align: middle;
}

.filter-card,
.table-card {
  margin-bottom: 16px;
  position: relative;
  z-index: 1;
  background: rgba(255, 255, 255, 0.95);
  backdrop-filter: blur(10px);
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.08);
}

.filter-form {
  display: flex;
  align-items: center;
  gap: 12px;
}

.filter-actions {
  display: flex;
  gap: 12px;
}

.toolbar {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 16px;
}

.hidden-file-input {
  display: none;
}

.device-type-table {
  width: 100%;
}

.code-field {
  display: flex;
  align-items: center;
  gap: 12px;
}

.name-cell {
  display: flex;
  align-items: center;
  position: relative;
}

.tree-arrow {
  width: 20px;
  height: 20px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  color: #909399;
  cursor: pointer;
  transition: transform 0.2s ease;
}

.tree-arrow-empty {
  cursor: default;
}

.tree-indent {
  display: inline-block;
}

.tree-node-label {
  white-space: nowrap;
}

/* 层级样式 */
.level-1 .tree-indent {
  padding-left: 0 !important;
}

.level-2 .tree-indent {
  padding-left: 20px !important;
}

.level-3 .tree-indent {
  padding-left: 40px !important;
}

.level-4 .tree-indent {
  padding-left: 60px !important;
}

/* 可展开节点样式 */
.tree-arrow:hover {
  color: #409eff;
}
</style>